package com.ds.robot.assistant.service;

import com.google.common.collect.Lists;
import com.ds.robot.assistant.model.QxUserResp;
import com.ds.robot.assistant.model.QxUserResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.*;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
import org.springframework.web.client.HttpClientErrorException;
import org.springframework.web.client.RestClientException;
import org.springframework.web.client.RestTemplate;

import javax.annotation.Resource;
import java.util.*;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.CompletionException;
import java.util.concurrent.ExecutorService;

/**
 * 作用：
 * 参考文档：https://developer.work.weixin.qq.com/document/path/90196
 *
 * @author WeiShaoying
 * 
 */
@Service
@Slf4j
public class QxUserApiService {

    private final String baseUrl = "https://qyapi.weixin.qq.com/cgi-bin/user/simplelist?access_token=%s&department_id=%s";

    private final List<String> departmentIdList = Lists.newArrayList("20", "1436", "2620", "3016");

    @Value("${qx.access_token_key}")
    private String accessTokenKey;

    @Value("${qx.access_token_api}")
    private String accessTokenApiUrl;

    @Resource
    private ExecutorService executorService;

    @Autowired
    private RestTemplate restTemplate;

    // @Autowired
    // private RedisTemplate redisTemplate;

    public List<QxUserResp> queryAllUsers2() {
        List<CompletableFuture<QxUserResponse>> completableFutureList = Lists.newArrayList();
        for (String id : departmentIdList) {
            CompletableFuture<QxUserResponse> future = CompletableFuture.supplyAsync(() -> fetchUsersByDepartmentId(id), executorService);
            completableFutureList.add(future);
        }
        CompletableFuture.allOf(completableFutureList.toArray(new CompletableFuture[0]))
                .exceptionally(throwable -> {
                    log.error("fetchUsersByDepartmentId error", throwable);
                    return null;
                }).join();
        Set<QxUserResp> userSet = new HashSet<>();
        for (CompletableFuture<QxUserResponse> future : completableFutureList) {
            QxUserResponse response = future.join();
            if (response != null && !CollectionUtils.isEmpty(response.getUserlist())) {
                userSet.addAll(response.getUserlist());
            }
        }
        return Lists.newArrayList(userSet);
    }

    public List<QxUserResp> queryAllUsers() {
        Set<QxUserResp> userSet = new HashSet<>();
        // 异步获取所有部门的用户信息
        CompletableFuture<Void> allFutures = CompletableFuture.allOf(
                departmentIdList.stream().map(departmentId ->
                        CompletableFuture.supplyAsync(() -> fetchUsersByDepartmentId(departmentId), executorService)
                                .thenAccept(response -> {
                                    if (response != null && !CollectionUtils.isEmpty(response.getUserlist())) {
                                        userSet.addAll(response.getUserlist());
                                    }
                                }).exceptionally(throwable -> {
                                    log.error("fetchUsersByDepartmentId error : {}", departmentId, throwable);
                                    return null;
                                })
                ).toArray(CompletableFuture[]::new)
        );
        try {
            allFutures.join();
        } catch (CompletionException ex) {
            log.error("queryAllUsers join error", ex);
        }
        return new ArrayList<>(userSet);
    }


    // public QxUserResponse fetchUsers() {
    //     String url = String.format(baseUrl, accessToken, "20");
    //     try {
    //         ResponseEntity<QxUserResponse> response = restTemplate.getForEntity(url, QxUserResponse.class);
    //         if (response.getStatusCode().is2xxSuccessful()) {
    //             return response.getBody();
    //         } else {
    //             // 处理非2xx
    //             throw new RuntimeException("Failed to fetch users: " + response.getStatusCode());
    //         }
    //     } catch (HttpClientErrorException e) {
    //         // 处理4xx客户端错误
    //         throw new RuntimeException("Client error while fetching users: " + e.getStatusCode(), e);
    //     } catch (RestClientException e) {
    //         // 处理其他RestClient异常，如连接超时等
    //         throw new RuntimeException("Error while fetching users", e);
    //     }
    // }

    public QxUserResponse fetchUsersByDepartmentId(String departmentId) {
        // String accessToken = (String) redisTemplate.opsForValue().get(accessTokenKey);
        String accessToken = queryAccessToken();
        if (!StringUtils.hasText(accessToken)) {
            throw new RuntimeException("QX API accessToken is empty");
        }
        log.info("当前accessToken: {}", accessToken);
        String url = String.format(baseUrl, accessToken, departmentId);
        log.info("请求fetchUsersByDepartmentId url: {}", url);
        HttpHeaders headers = new HttpHeaders();
        headers.setAccept(Collections.singletonList(MediaType.APPLICATION_JSON));
        HttpEntity<String> entity = new HttpEntity<>(headers);

        try {
            ResponseEntity<QxUserResponse> response = restTemplate.exchange(url, HttpMethod.GET, entity, QxUserResponse.class);
            if (response.getStatusCode().is2xxSuccessful()) {
                return response.getBody();
            } else {
                // 处理非2xx
                throw new RuntimeException("Failed to fetch users: " + response.getStatusCode());
            }
        } catch (HttpClientErrorException e) {
            // 处理4xx客户端错误
            throw new RuntimeException("Client error while fetching users: " + e.getStatusCode(), e);
        } catch (RestClientException e) {
            // 处理其他RestClient异常，如连接超时等
            throw new RuntimeException("Error while fetching users", e);
        }
    }

    public String queryAccessToken() {
        try {
            ResponseEntity<String> responseEntity = restTemplate.getForEntity(accessTokenApiUrl, String.class);
            // 检查响应状态码
            if (responseEntity.getStatusCode() == HttpStatus.OK) {
                String responseBody = responseEntity.getBody();
                if (responseBody != null && !responseBody.isEmpty()) {
                    return responseBody;
                } else {
                    // 空响应体
                    throw new IllegalStateException("查询accessToken失败");
                }
            } else {
                // 处理非200状态码的情况
                throw new IllegalStateException("查询accessToken API returned non-OK status: " + responseEntity.getStatusCode());
            }
        } catch (HttpClientErrorException e) {
            // 处理4xx客户端错误
            throw new RuntimeException("Client error while queryAccessToken: " + e.getStatusCode(), e);
        } catch (RestClientException e) {
            // 处理其他RestClient异常，如连接超时等
            throw new RuntimeException("Error while queryAccessToken", e);
        } catch (Exception e) {
            // 处理其他未预见的异常
            throw new RuntimeException("An unexpected error occurred", e);
        }
    }

}
